package com.qlshouyu.gateway.client.block.starter;

import com.qlshouyu.gateway.client.Bootgateway;
import com.qlshouyu.gateway.client.model.Application;
import com.qlshouyu.gateway.client.model.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.*;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

public class LoadBalancerBootgateway {
    private final static Logger LOGGER = LoggerFactory.getLogger(LoadBalancerBootgateway.class);
    private String lbAddr;
    private Bootgateway bootgateway;
    private LoadBalancerClient loadBalancerClient;

    public LoadBalancerBootgateway(LoadBalancerClientFactory clientFactory, String lbAddr, Bootgateway bootgateway) {
        this.lbAddr = lbAddr;
        this.bootgateway = bootgateway;
        this.loadBalancerClient = new BlockingLoadBalancerClient(clientFactory);
    }


    /**
     * 创建应用
     *
     * @param application
     * @return
     */
    public Application createApplication(Application application) throws Exception {
        return this.bootgateway.createApplication(choose(), application);
    }

    /**
     * 根据应用编码获取应用信息
     *
     * @param code
     * @return
     */
    public Application getApplicationByCode(String code) throws Exception {
        return this.bootgateway.getApplicationByCode(choose(), code);
    }

    public List<Service> getServiceList() throws Exception {
        return this.bootgateway.getServiceList(choose());
    }


    private String choose() throws Exception {
        String serviceId = verifyAndGetInstanceName();
        ServiceInstance instance = this.loadBalancerClient.choose(serviceId);
        if (instance == null) {
            LOGGER.warn("Unable to find instance for " + serviceId);
//            throw new NotFoundException("Unable to find instance for " + serviceId);
        }

        String overrideScheme = instance.isSecure() ? "https" : "http";
        String addr = overrideScheme + "://" + instance.getHost() + ":" + instance.getPort();
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("getApplicationByCode from: {}", addr);
        }
        return addr;
    }

    private String verifyAndGetInstanceName() throws Exception {
        URI url = null;
        try {
            url = new URI(this.lbAddr);
        } catch (URISyntaxException e) {
            throw new Exception("URISyntaxException:" + e.getMessage());
        }
        if (url == null || !"lb".equals(url.getScheme())) {
            throw new Exception("Service id error");
        }
        return url.getHost();
    }
}
